﻿/*! @file
********************************************************************************
<PRE>
文 件 名    : CSProjFile.cs
说    明    : 获取.CSProj的附属文件
作    者    : 汪泽然
--------------------------------------------------------------------------------
备    注    : 
--------------------------------------------------------------------------------
修改记录: 
 * 日    期    版  本    修改人    修改内容 
 * 2009-7-9    0.1.0     汪泽然    
</PRE>
********************************************************************************
* 版权所有(c) 2008 ~ 2009, 汪泽然, 保留所有权利
*******************************************************************************/
using System;
using System.Text;
using System.Collections.Generic;
using System.Text.RegularExpressions;

using Wangzeran.Transform.Core.Util;
using Wangzeran.Transform.Core.ITransform;
using Wangzeran.Transform.Core.TransformException;


namespace Wangzeran.Transform.PlugIn.SubFiles
{
    /// <summary>
    /// 获取 项目文件
    /// </summary>
    public class CSProjFile : IChildFile
    {

        #region Common Variables

        /// <summary>
        /// 替换项目路径
        /// </summary>
        private const string REPLACE_FRONT = "Project(.*) = \"\\S*\",";
        /// <summary>
        /// 
        /// </summary>
        private const string REPLACE_REAR = ",+?.*\\s.*";
        /// <summary>
        /// 
        /// </summary>
        private const string REPLACE_MARK = "\"";
        /// <summary>
        /// 匹配绝对路径
        /// </summary>
        private const string PATTERN_ABSOLUTEPATH = @"\w:\\";
        /// <summary>
        /// 匹配项目行信息
        /// </summary>
        public const string PATTERN_PROJECT = @"Project\(.*";

        #endregion


        #region IGetSubFile 成员

        /// <summary>
        /// 获取项目文件列表
        /// </summary>
        /// <param name="filePath">解决方案文件路径</param>
        /// <param name="lstSubFiles">项目文件列表集合</param>
        /// <returns></returns>
        public bool GetChildFiles(string filePath, IList<string> lstSubFiles)
        {
            try
            {
                // 获取整个项目的基路径
                string path = filePath.Remove(filePath.LastIndexOf(@"\") + 1);

                string content = TransformUtil.GetFileContent(filePath);

                // 匹配项目段信息
                // Project ~ EndProject
                MatchCollection matchs = Regex.Matches(content, PATTERN_PROJECT);
                // 将获取的Project段信息加入集合
                foreach (Match match in matchs)
                {
                    lstSubFiles.Add(match.Value);
                }

                // 处理每组项目信息，获取项目文件（.csproj）的绝对路径
                for (int i = 0; i < lstSubFiles.Count; i++)
                {
                    string value = lstSubFiles[i];

                    lstSubFiles[i] = GetProjFilePath(value, path);
                }

                return true;
            }
            catch (Exception ex)
            {
                throw new UnGetSubFileException(filePath, ex.Message);
            }
        }

        #endregion


        #region Assist Method

        /// <summary>
        /// 获取项目段信息中项目文件的完整路径
        /// </summary>
        /// <param name="value">包含项目路径信息的段首字符串</param>
        /// <param name="path">项目基路径</param>
        /// <returns>项目文件的完整路径</returns>
        private string GetProjFilePath(string value, string path)
        {
            try
            {
                // 三个正则表达式的结果，就是为了获取该项目的.CSProj的路径
                value = Regex.Replace(value, REPLACE_FRONT, String.Empty, RegexOptions.IgnoreCase);
                value = Regex.Replace(value, REPLACE_REAR, String.Empty, RegexOptions.IgnoreCase);
                value = Regex.Replace(value, REPLACE_MARK, String.Empty, RegexOptions.IgnoreCase);

                // 如果项目路径与解决方案所在同一目录，则置为空值
                if (value.Trim() == ".")
                {
                    value = String.Empty;
                }

                // 如果项目路径不是绝对路径，则 项目路径 = 解决方案路径 + 项目相对路径
                if (!Regex.IsMatch(value, PATTERN_ABSOLUTEPATH, RegexOptions.IgnoreCase))
                {
                    value = path + value.Trim();
                }

                return value;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        } 

        #endregion

    }
}
